cmake_minimum_required(VERSION 3.28)
project(modern_cpp)

# 设置C++标准
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 添加开关选项以控制是否使用no_elide_constructors库
option(USE_NO_ELIDE_CONSTRUCTORS "Use no_elide_constructors interface library" OFF)

if (USE_NO_ELIDE_CONSTRUCTORS)
    # 创建INTERFACE库并设置编译选项
    add_library(no_elide_constructors INTERFACE)
    target_compile_options(no_elide_constructors INTERFACE -fno-elide-constructors)
endif ()

# 自定义函数用于链接库并显示警告
function(link_no_elide_constructors target)
    if (USE_NO_ELIDE_CONSTRUCTORS)
        target_link_libraries(${target} PRIVATE no_elide_constructors)
        message(WARNING "Target ${target} is using no_elide_constructors interface library with -fno-elide-constructors flag.")
    endif ()
endfunction()

# 指定输出目录
if (WIN32)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/windows/bin)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/windows/lib)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/windows/lib)
elseif (UNIX)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/unix/bin)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/unix/lib)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/unix/lib)
endif ()

# 获取当前目录下所有的 .cpp 文件
file(GLOB SOURCES "*.cpp")

foreach (SOURCE ${SOURCES})
    # 获取源文件的文件名（不包括扩展名）
    get_filename_component(TARGET_NAME ${SOURCE} NAME_WE)

    # 添加可执行文件
    add_executable(${TARGET_NAME} ${SOURCE})

    # 链接INTERFACE库到目标，并显示警告
    link_no_elide_constructors(${TARGET_NAME})

    # 为每个可执行文件设置输出目录
    if (WIN32)
        set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/windows/bin)
    elseif (UNIX)
        set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_build/unix/bin)
    endif ()
endforeach ()

# 包含 book_src 目录
add_subdirectory(book_src)
